package com.ljf.task.domain.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ljf.authority.domain.repository.AuthorityBaseMenuTabulationRepository;
import com.ljf.authority.dto.query.AuthorityBaseMenuTabulationQuery;
import com.ljf.authority.vo.AuthorityBaseMenuTabulationVO;
import com.ljf.common.domain.service.BasisDomainService;
import com.ljf.common.exception.ServiceException;
import com.ljf.common.utils.CollectionUtil;
import com.ljf.common.utils.DateUtil;
import com.ljf.common.utils.EnumUtil;
import com.ljf.common.vo.BasicCardTimeLineVO;
import com.ljf.config.domain.service.TaskConfigDatKeyValueDomainService;
import com.ljf.config.enums.TaskConfigDatKeyValueEnum;
import com.ljf.task.domain.repository.TaskDatTaskDetailRepository;
import com.ljf.task.domain.repository.TaskDatTaskOperateRepository;
import com.ljf.task.domain.repository.TaskDatTaskTabulationRepository;
import com.ljf.task.dto.command.*;
import com.ljf.task.dto.query.TaskDatTaskDetailQuery;
import com.ljf.task.dto.query.TaskDatTaskOperateQuery;
import com.ljf.task.dto.query.TaskDatTaskTabulationQuery;
import com.ljf.task.enums.*;
import com.ljf.task.model.TaskDatTaskDetail;
import com.ljf.task.model.TaskDatTaskOperate;
import com.ljf.task.model.TaskDatTaskTabulation;
import com.ljf.task.vo.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务列表  领域服务
 *
 * @author LJF
 * @since 2024-12-25
 */
@Component
@AllArgsConstructor
public class TaskDatTaskTabulationDomainService extends BasisDomainService<TaskDatTaskTabulationRepository, TaskDatTaskTabulationQuery, TaskDatTaskTabulationVO, TaskDatTaskTabulation, TaskDatTaskTabulationCommand> {

    @Resource
    private TaskConfigDatKeyValueDomainService taskConfigDatKeyValueDomainService;

    private final TaskDatTaskDetailRepository detailRepository;
    private final TaskDatTaskOperateRepository operateRepository;
    private final AuthorityBaseMenuTabulationRepository authorityBaseMenuTabulationRepository;

    @Override
    public TaskDatTaskTabulation add(TaskDatTaskTabulationCommand command) throws ServiceException {
        TaskDatTaskTabulation model = TaskDatTaskTabulation.builder()
                .menuCode(command.getMenuCode())
                .title(command.getTitle())
                .taskStatus(TaskDatTaskTabulationTaskStatusEnum.TO_BE_DESIGNED.getCode())
                .taskType(command.getTaskType())
                .build();
        repository.insert(model);
        List<TaskDatTaskOperate> operateList = new ArrayList<>();
        operateList.add(buildTaskOperate(model.getCode(), TaskDatTaskOperateOperationTypeEnum.CREATED));
        operateList.add(buildTaskOperateByStatus(model.getCode(), TaskDatTaskTabulationTaskStatusEnum.TO_BE_DESIGNED.getCode()));
        operateRepository.insertBatch(operateList);
        return model;
    }

    @Override
    public Page<TaskDatTaskTabulationVO> query(TaskDatTaskTabulationQuery query) throws ServiceException {
        Page<TaskDatTaskTabulationVO> page = super.query(query);
        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            List<String> menuCodeList = page.getRecords().stream()
                    .map(TaskDatTaskTabulationVO::getMenuCode).distinct().collect(Collectors.toList());
            List<AuthorityBaseMenuTabulationVO> menuTabulationList = authorityBaseMenuTabulationRepository.selectList(
                    AuthorityBaseMenuTabulationQuery.builder().codeList(menuCodeList).build()
            );
            Map<String, String> menuTabulationMap = menuTabulationList.stream().collect(Collectors.toMap(
                    AuthorityBaseMenuTabulationVO::getCode,
                    AuthorityBaseMenuTabulationVO::getName,
                    (a, b) -> a)
            );
            for (TaskDatTaskTabulationVO tabulation : page.getRecords()) {
                tabulation.setMenuName(menuTabulationMap.getOrDefault(tabulation.getMenuCode(), ""));
            }
        }
        return page;
    }

    @Override
    public Boolean edit(TaskDatTaskTabulationCommand command) throws ServiceException {
        TaskDatTaskTabulation updateModel = TaskDatTaskTabulation.builder()
                .id(command.getId())
                .menuCode(command.getMenuCode())
                .title(command.getTitle())
                .build();
        TaskDatTaskTabulationVO model = repository.selectById(command.getId());
        List<TaskDatTaskOperate> operateList = new ArrayList<>();
        operateList.add(buildTaskOperate(model.getCode(), TaskDatTaskOperateOperationTypeEnum.UPDATED));
        operateRepository.insertBatch(operateList);
        return repository.updateById(updateModel) > 0;
    }

    /**
     * 更新任务状态
     *
     * @param command
     * @throws ServiceException
     */
    public void editTaskStatus(TaskDatTaskTabulationTaskStatusCommand command) throws ServiceException {
        TaskDatTaskTabulationVO model = repository.selectById(command.getId());
        Integer detailStatus = null;
        boolean deleteDetail= false;
        List<TaskDatTaskOperate> operateList = new ArrayList<>();
        if (command.getTaskStatus() < model.getTaskStatus()) {
            int taskStatus = model.getTaskStatus();
            do {
                taskStatus--;
                if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.DEVELOPING.getCode())) {
                    detailStatus = TaskDatTaskDetailDetailStatusEnum.PROCESSING.getCode();
                }
                if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.TO_BE_DEVELOPED.getCode())) {
                    detailStatus = TaskDatTaskDetailDetailStatusEnum.PENDING_PROCESSING.getCode();
                }
                if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.DESIGN.getCode())) {
                    detailStatus = TaskDatTaskDetailDetailStatusEnum.PENDING_PROCESSING.getCode();
                }
                if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.TO_BE_DESIGNED.getCode())) {
                    deleteDetail = true;
                }
            }
            while (command.getTaskStatus() < taskStatus);
            operateList.add(buildTaskOperate(model.getCode(), TaskDatTaskOperateOperationTypeEnum.STATUS_UPDATED));
        }
        if (deleteDetail) {
            detailRepository.delete(TaskDatTaskDetailQuery.builder().code(model.getCode()).build());
        }
        else if (detailStatus != null) {
            detailRepository.update(
                    TaskDatTaskDetail.builder().detailStatus(detailStatus).build(),
                    TaskDatTaskDetailQuery.builder().code(model.getCode()).build()
            );
        }
        repository.updateById(
                TaskDatTaskTabulation.builder().id(command.getId()).taskStatus(command.getTaskStatus()).build()
        );
        operateList.add(buildTaskOperateByStatus(model.getCode(), command.getTaskStatus()));
        operateRepository.insertBatch(operateList);
    }

    /**
     * 获取提交信息文本
     *
     * @param id
     * @return
     * @throws ServiceException
     */
    public String queryCommitMessageById(Long id) throws ServiceException {
        TaskDatTaskTabulationVO task = repository.selectById(id);
        String format;
        if (Objects.equals(task.getTaskType(), TaskDatTaskTabulationTaskTypeEnum.BUG_FIXES.getCode())) {
            format = taskConfigDatKeyValueDomainService.getStringByKey(TaskConfigDatKeyValueEnum.TASK_TABULATION_COMMIT_REPAIR_BUG_MESSAGE_FORMAT);
        }
        else {
            format = taskConfigDatKeyValueDomainService.getStringByKey(TaskConfigDatKeyValueEnum.TASK_TABULATION_COMMIT_FUNCTION_MESSAGE_FORMAT);
        }
        return String.format(format, task.getCode() + " " + task.getTitle());
    }

    /**
     * 根据ID查询任务设计信息
     *
     * @param id
     * @return
     * @throws ServiceException
     */
    public TaskDatTaskTabulationDesignMessageVO queryDesignMessageById(Long id) throws ServiceException {
        TaskDatTaskTabulationVO task = repository.selectById(id);
        AuthorityBaseMenuTabulationVO menuTabulation = authorityBaseMenuTabulationRepository.selectOne(
                AuthorityBaseMenuTabulationQuery.builder().code(task.getMenuCode()).build()
        );
        TaskDatTaskTabulationTaskTypeEnum taskTypeEnum = EnumUtil.getEnumByCode(task.getTaskType(), TaskDatTaskTabulationTaskTypeEnum.values());
        if (taskTypeEnum == null) {
            throw new ServiceException("根据ID查询任务设计信息异常: 任务类型不存在");
        }
        List<TaskDatTaskDetailVO> detailList = detailRepository.selectList(
                TaskDatTaskDetailQuery.builder().code(task.getCode()).build()
        );
        List<TaskDatTaskDetailDesignMessageVO> databaseProcessingList = new ArrayList<>();
        List<TaskDatTaskDetailVO> databaseProcessingDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.DATABASE_PROCESSING.getCode()))
                .sorted(Comparator.comparing(TaskDatTaskDetailVO::getSort))
                .collect(Collectors.toList());
        this.fillDesignMessage(databaseProcessingList, databaseProcessingDetailList);
        List<TaskDatTaskDetailDesignMessageVO> frontEndDevelopmentList = new ArrayList<>();
        List<TaskDatTaskDetailVO> frontEndDevelopmentDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.FRONT_END_DEVELOPMENT.getCode()))
                .sorted(Comparator.comparing(TaskDatTaskDetailVO::getSort))
                .collect(Collectors.toList());
        this.fillDesignMessage(frontEndDevelopmentList, frontEndDevelopmentDetailList);
        List<TaskDatTaskDetailDesignMessageVO> backendDevelopmentList = new ArrayList<>();
        List<TaskDatTaskDetailVO> backendDevelopmentDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.BACKEND_DEVELOPMENT.getCode()))
                .sorted(Comparator.comparing(TaskDatTaskDetailVO::getSort))
                .collect(Collectors.toList());
        this.fillDesignMessage(backendDevelopmentList, backendDevelopmentDetailList);
        return TaskDatTaskTabulationDesignMessageVO.builder()
                .code(task.getCode())
                .menuCode(task.getMenuCode())
                .menuName(menuTabulation.getName())
                .title(task.getTitle())
                .databaseProcessing(taskTypeEnum.getDatabaseProcessing())
                .frontEndDevelopment(taskTypeEnum.getFrontEndDevelopment())
                .backendDevelopment(taskTypeEnum.getBackendDevelopment())
                .databaseProcessingList(databaseProcessingList)
                .frontEndDevelopmentList(frontEndDevelopmentList)
                .backendDevelopmentList(backendDevelopmentList)
                .build();
    }

    /**
     * 更新任务明细草稿
     *
     * @param command
     * @throws ServiceException
     */
    public void editDetailDraft(TaskDatTaskTabulationDesignCommand command) throws ServiceException {
        TaskDatTaskTabulationVO model = repository.selectById(command.getId());
        this.editDetail(model, command);
        List<TaskDatTaskOperate> operateList = new ArrayList<>();
        operateList.add(buildTaskOperate(model.getCode(), TaskDatTaskOperateOperationTypeEnum.DESIGN_DRAFT));
        if (!Objects.equals(model.getTaskStatus(), TaskDatTaskTabulationTaskStatusEnum.DESIGN.getCode())) {
            repository.updateById(
                    TaskDatTaskTabulation.builder()
                            .id(model.getId())
                            .taskStatus(TaskDatTaskTabulationTaskStatusEnum.DESIGN.getCode())
                            .build()
            );
            operateList.add(buildTaskOperateByStatus(model.getCode(), TaskDatTaskTabulationTaskStatusEnum.DESIGN.getCode()));
        }
        operateRepository.insertBatch(operateList);

    }

    /**
     * 更新任务明细终稿
     *
     * @param command
     * @throws ServiceException
     */
    public void editDetailFinalDraft(TaskDatTaskTabulationDesignCommand command) throws ServiceException {
        TaskDatTaskTabulationVO model = repository.selectById(command.getId());
        this.editDetail(model, command);
        List<TaskDatTaskOperate> operateList = new ArrayList<>();
        operateList.add(buildTaskOperate(model.getCode(), TaskDatTaskOperateOperationTypeEnum.DESIGN_DRAFT));
        repository.updateById(
                TaskDatTaskTabulation.builder()
                        .id(model.getId())
                        .taskStatus(TaskDatTaskTabulationTaskStatusEnum.TO_BE_DEVELOPED.getCode())
                        .build()
        );
        operateList.add(buildTaskOperate(model.getCode(), TaskDatTaskOperateOperationTypeEnum.DESIGN_FINISHED));
        operateList.add(buildTaskOperateByStatus(model.getCode(), TaskDatTaskTabulationTaskStatusEnum.TO_BE_DEVELOPED.getCode()));
        operateRepository.insertBatch(operateList);
    }

    /**
     * 根据ID查询任务开发信息
     *
     * @param id
     * @return
     * @throws ServiceException
     */
    public TaskDatTaskTabulationDevelopMessageVO queryDevelopMessageById(Long id) throws ServiceException {
        TaskDatTaskTabulationVO task = repository.selectById(id);
        AuthorityBaseMenuTabulationVO menuTabulation = authorityBaseMenuTabulationRepository.selectOne(
                AuthorityBaseMenuTabulationQuery.builder().code(task.getMenuCode()).build()
        );
        TaskDatTaskTabulationTaskTypeEnum taskTypeEnum = EnumUtil.getEnumByCode(task.getTaskType(), TaskDatTaskTabulationTaskTypeEnum.values());
        if (taskTypeEnum == null) {
            throw new ServiceException("根据ID查询任务开发信息异常: 任务类型不存在");
        }
        List<TaskDatTaskDetailVO> detailList = detailRepository.selectList(
                TaskDatTaskDetailQuery.builder().code(task.getCode()).build()
        );
        List<TaskDatTaskDetailDevelopMessageVO> databaseProcessingList = new ArrayList<>();
        List<TaskDatTaskDetailVO> databaseProcessingDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.DATABASE_PROCESSING.getCode()))
                .sorted(Comparator.comparing(TaskDatTaskDetailVO::getSort))
                .collect(Collectors.toList());
        this.fillDevelopMessage(databaseProcessingList, databaseProcessingDetailList);
        List<TaskDatTaskDetailDevelopMessageVO> frontEndDevelopmentList = new ArrayList<>();
        List<TaskDatTaskDetailVO> frontEndDevelopmentDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.FRONT_END_DEVELOPMENT.getCode()))
                .sorted(Comparator.comparing(TaskDatTaskDetailVO::getSort))
                .collect(Collectors.toList());
        this.fillDevelopMessage(frontEndDevelopmentList, frontEndDevelopmentDetailList);
        List<TaskDatTaskDetailDevelopMessageVO> backendDevelopmentList = new ArrayList<>();
        List<TaskDatTaskDetailVO> backendDevelopmentDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.BACKEND_DEVELOPMENT.getCode()))
                .sorted(Comparator.comparing(TaskDatTaskDetailVO::getSort))
                .collect(Collectors.toList());
        this.fillDevelopMessage(backendDevelopmentList, backendDevelopmentDetailList);
        return TaskDatTaskTabulationDevelopMessageVO.builder()
                .code(task.getCode())
                .menuCode(task.getMenuCode())
                .menuName(menuTabulation.getName())
                .title(task.getTitle())
                .databaseProcessing(taskTypeEnum.getDatabaseProcessing())
                .frontEndDevelopment(taskTypeEnum.getFrontEndDevelopment())
                .backendDevelopment(taskTypeEnum.getBackendDevelopment())
                .databaseProcessingList(databaseProcessingList)
                .frontEndDevelopmentList(frontEndDevelopmentList)
                .backendDevelopmentList(backendDevelopmentList)
                .build();
    }

    /**
     * 更新任务明细开发状态
     *
     * @param command
     * @throws ServiceException
     */
    public void editDetailDevelopStatus(TaskDatTaskDetailStatusCommand command) throws ServiceException {
        List<TaskDatTaskOperate> operateList = new ArrayList<>();
        detailRepository.updateById(
                TaskDatTaskDetail.builder().id(command.getId()).detailStatus(command.getDetailStatus()).build()
        );
        TaskDatTaskDetailVO detail = detailRepository.selectById(command.getId());
        operateList.add(buildTaskOperateDetailByStatus(detail.getCode(), detail.getDetailType(), detail.getSort(), command.getDetailStatus()));
        this.refreshTaskStatus(detail.getCode(), operateList);
    }

    /**
     * 根据ID查询任务开发提交内容
     *
     * @param id
     * @return
     * @throws ServiceException
     */
    public String queryDetailSubmitMessageById(Long id) throws ServiceException {
        TaskDatTaskDetailVO detail = detailRepository.selectById(id);
        TaskDatTaskTabulationVO task = repository.selectOne(TaskDatTaskTabulationQuery.builder().code(detail.getCode()).build());
        TaskDatTaskTabulationTaskTypeEnum taskTypeEnum = EnumUtil.getEnumByCode(task.getTaskType(), TaskDatTaskTabulationTaskTypeEnum.values());
        if (taskTypeEnum == null) {
            throw new ServiceException("根据ID查询任务开发提交内容异常: 任务类型异常");
        }
        AuthorityBaseMenuTabulationVO menuTabulation = authorityBaseMenuTabulationRepository.selectOne(
                AuthorityBaseMenuTabulationQuery.builder().code(task.getMenuCode()).build()
        );
        return taskTypeEnum.getSubmitPrefix() + " " + task.getCode() + " " + menuTabulation.getName() + " " + task.getTitle() + "-" + detail.getTitle();
    }

    /**
     * 根据ID查询任务状态
     *
     * @param id
     * @return
     * @throws ServiceException
     */
    public TaskDatTaskTabulationTaskStatusVO queryTaskStatusById(Long id) throws ServiceException {
        TaskDatTaskTabulationVO model = repository.selectById(id);
        AuthorityBaseMenuTabulationVO menuTabulation = authorityBaseMenuTabulationRepository.selectOne(
                AuthorityBaseMenuTabulationQuery.builder().code(model.getMenuCode()).build()
        );
        return TaskDatTaskTabulationTaskStatusVO.builder()
                .code(model.getCode())
                .menuCode(model.getMenuCode())
                .menuName(menuTabulation.getName())
                .title(model.getTitle())
                .taskStatus(model.getTaskStatus())
                .build();
    }

    @Override
    public boolean deleteBatch(List<Long> ids) throws ServiceException {
        List<TaskDatTaskTabulationVO> modelList = repository.selectListByIds(ids);
        List<TaskDatTaskOperate> operateList = new ArrayList<>();
        for (TaskDatTaskTabulationVO model : modelList) {
            operateList.add(buildTaskOperate(model.getCode(), TaskDatTaskOperateOperationTypeEnum.DELETED));
        }
        operateRepository.insertBatch(operateList);
        return super.deleteBatch(ids);
    }

    /**
     * 根据ID查询任务操作历史
     *
     * @param id
     * @return
     * @throws ServiceException
     */
    public List<BasicCardTimeLineVO> queryOperateHistoryById(Long id) throws ServiceException {
        List<BasicCardTimeLineVO> resultList = new ArrayList<>();
        TaskDatTaskTabulationVO model = repository.selectById(id);
        List<TaskDatTaskOperateVO> operateList = operateRepository.selectList(
                TaskDatTaskOperateQuery.builder().code(model.getCode()).build()
        );
        if (CollectionUtil.isNotEmpty(operateList)) {
            Map<Integer, String> operationTypeMap = EnumUtil.getCodeToNameMap(TaskDatTaskOperateOperationTypeEnum.values());
            Map<Integer, String> detailTypeMap = EnumUtil.getCodeToNameMap(TaskDatTaskDetailDetailTypeEnum.values());
            Set<Integer> titleOperationTypeSet = new HashSet<>();
            for (TaskDatTaskOperateOperationTypeEnum value : TaskDatTaskOperateOperationTypeEnum.values()) {
                if (Objects.equals(value.getIsTitle(), Boolean.TRUE)) {
                    titleOperationTypeSet.add(value.getCode());
                }
            }
            Map<Date, List<TaskDatTaskOperateVO>> timeToCodeMap = operateList.stream()
                    .collect(Collectors.groupingBy(TaskDatTaskOperateVO::getOperationTime));
            List<Date> keyList = new ArrayList<>(timeToCodeMap.keySet());
            keyList = keyList.stream().sorted(Comparator.comparing(Date::getTime).reversed()).collect(Collectors.toList());
            Integer code;
            List<String> textList;
            String text;
            for (Date date : keyList) {
                code = timeToCodeMap.get(date).get(0).getOperationType();
                textList = new ArrayList<>();
                for (TaskDatTaskOperateVO operateVO : timeToCodeMap.get(date)) {
                    if (titleOperationTypeSet.contains(operateVO.getOperationType())) {
                        code = operateVO.getOperationType();
                    }
                }
                for (TaskDatTaskOperateVO operateVO : timeToCodeMap.get(date)) {
                    if (!Objects.equals(code, operateVO.getOperationType())) {
                        if (operateVO.getDetailType() != null && operateVO.getDetailType() != 0) {
                            text = detailTypeMap.getOrDefault(operateVO.getDetailType(), "");
                            textList.add(operationTypeMap.getOrDefault(operateVO.getOperationType(), "") + "-" + text + "-步骤" + operateVO.getSort());
                        }
                        else {
                            textList.add(operationTypeMap.getOrDefault(operateVO.getOperationType(), ""));
                        }
                    }
                }
                resultList.add(
                        BasicCardTimeLineVO.builder()
                                .time(DateUtil.format(date))
                                .title(operationTypeMap.getOrDefault(code, ""))
                                .textList(textList)
                                .build()
                );
            }
        }
        return resultList;
    }

    /**
     * 刷新明细状态
     *
     * @param code
     * @param operateList
     * @throws ServiceException
     */
    private void refreshTaskStatus(String code, List<TaskDatTaskOperate> operateList) throws ServiceException {
        TaskDatTaskTabulationVO task = repository.selectOne(TaskDatTaskTabulationQuery.builder().code(code).build());
        List<TaskDatTaskDetailVO> detailList = detailRepository.selectList(
                TaskDatTaskDetailQuery.builder().code(code).build()
        );
        Map<Integer, Long> taskStatusCountMap = detailList.stream()
                .collect(Collectors.groupingBy(TaskDatTaskDetailVO::getDetailStatus, Collectors.counting()));
        Integer taskStatus;
        if (taskStatusCountMap.getOrDefault(TaskDatTaskDetailDetailStatusEnum.COMPLETED.getCode(), 0L) == detailList.size()) {
            taskStatus = TaskDatTaskTabulationTaskStatusEnum.JOINT_DEBUGGING_IN_PROGRESS.getCode();
        }
        else if (taskStatusCountMap.getOrDefault(TaskDatTaskDetailDetailStatusEnum.PENDING_PROCESSING.getCode(), 0L) == detailList.size()) {
            taskStatus = TaskDatTaskTabulationTaskStatusEnum.TO_BE_DEVELOPED.getCode();
        }
        else {
            taskStatus = TaskDatTaskTabulationTaskStatusEnum.DEVELOPING.getCode();
        }
        if (!Objects.equals(task.getTaskStatus(), taskStatus)) {
            repository.updateById(TaskDatTaskTabulation.builder().id(task.getId()).taskStatus(taskStatus).build());
            if (Objects.equals(TaskDatTaskTabulationTaskStatusEnum.JOINT_DEBUGGING_IN_PROGRESS.getCode(), taskStatus)) {
                operateList.add(buildTaskOperate(code, TaskDatTaskOperateOperationTypeEnum.DEVELOP_FINISHED));
            }
            operateList.add(buildTaskOperateByStatus(code, taskStatus));
        }
        operateRepository.insertBatch(operateList);
    }

    /**
     * 编辑任务明细
     *
     * @param model
     * @param command
     * @throws ServiceException
     */
    private void editDetail(TaskDatTaskTabulationVO model, TaskDatTaskTabulationDesignCommand command) throws ServiceException {
        List<TaskDatTaskDetailVO> detailList = detailRepository.selectList(
                TaskDatTaskDetailQuery.builder().code(model.getCode()).build()
        );
        List<TaskDatTaskDetail> needInsertList = new ArrayList<>();
        List<TaskDatTaskDetail> needUpdateList = new ArrayList<>();
        List<Long> needDeleteList = new ArrayList<>();
        List<TaskDatTaskDetailVO> dataBaseDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.DATABASE_PROCESSING.getCode()))
                .collect(Collectors.toList());
        this.handleDetailList(model.getCode(), TaskDatTaskDetailDetailTypeEnum.DATABASE_PROCESSING, command.getDatabaseProcessingList(), dataBaseDetailList, needInsertList, needUpdateList, needDeleteList);
        List<TaskDatTaskDetailVO> fontEndDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.FRONT_END_DEVELOPMENT.getCode()))
                .collect(Collectors.toList());
        this.handleDetailList(model.getCode(), TaskDatTaskDetailDetailTypeEnum.FRONT_END_DEVELOPMENT, command.getFrontEndDevelopmentList(), fontEndDetailList, needInsertList, needUpdateList, needDeleteList);
        List<TaskDatTaskDetailVO> backendDetailList = detailList.stream()
                .filter(one -> Objects.equals(one.getDetailType(), TaskDatTaskDetailDetailTypeEnum.BACKEND_DEVELOPMENT.getCode()))
                .collect(Collectors.toList());
        this.handleDetailList(model.getCode(), TaskDatTaskDetailDetailTypeEnum.BACKEND_DEVELOPMENT, command.getBackendDevelopmentList(), backendDetailList, needInsertList, needUpdateList, needDeleteList);
        detailRepository.insertBatch(needInsertList);
        detailRepository.updateBatchByIds(needUpdateList);
        detailRepository.deleteBatchByIds(needDeleteList);
    }

    /**
     * 填充任务设计信息明细
     *
     * @param targetList
     * @param sourceList
     */
    private void fillDesignMessage(List<TaskDatTaskDetailDesignMessageVO> targetList, List<TaskDatTaskDetailVO> sourceList) {
        if (CollectionUtil.isEmpty(sourceList)) {
            return;
        }
        for (TaskDatTaskDetailVO source : sourceList) {
            targetList.add(
                    TaskDatTaskDetailDesignMessageVO.builder()
                            .id(source.getId())
                            .sort(source.getSort())
                            .title(source.getTitle())
                            .content(source.getContent())
                            .build()
            );
        }
    }

    /**
     * 填充任务开发信息明细
     *
     * @param targetList
     * @param sourceList
     */
    private void fillDevelopMessage(List<TaskDatTaskDetailDevelopMessageVO> targetList, List<TaskDatTaskDetailVO> sourceList) {
        if (CollectionUtil.isEmpty(sourceList)) {
            return;
        }
        Map<Integer, String> detailStatusMap = EnumUtil.getCodeToNameMap(TaskDatTaskDetailDetailStatusEnum.values());
        for (TaskDatTaskDetailVO source : sourceList) {
            targetList.add(
                    TaskDatTaskDetailDevelopMessageVO.builder()
                            .id(source.getId())
                            .sort(source.getSort())
                            .title(source.getTitle())
                            .content(source.getContent())
                            .detailStatus(source.getDetailStatus())
                            .detailStatusName(detailStatusMap.getOrDefault(source.getDetailStatus(), ""))
                            .build()
            );
        }
    }

    /**
     * 处理任务明细数据
     *
     * @param code
     * @param detailTypeEnum
     * @param commandList
     * @param detailList
     * @param needInsertList
     * @param needUpdateList
     * @param needDeleteList
     */
    private void handleDetailList(String code, TaskDatTaskDetailDetailTypeEnum detailTypeEnum, List<TaskDatTaskDetailCommand> commandList, List<TaskDatTaskDetailVO> detailList, List<TaskDatTaskDetail> needInsertList, List<TaskDatTaskDetail> needUpdateList, List<Long> needDeleteList) {
        if (CollectionUtil.isEmpty(commandList) && CollectionUtil.isEmpty(detailList)) {
            return;
        }
        if (CollectionUtil.isEmpty(commandList)) {
            List<Long> ids = detailList.stream().map(TaskDatTaskDetailVO::getId).distinct().collect(Collectors.toList());
            needDeleteList.addAll(ids);
            return;
        }
        if (CollectionUtil.isEmpty(detailList)) {
            for (TaskDatTaskDetailCommand detailCommand : commandList) {
                needInsertList.add(
                        TaskDatTaskDetail.builder()
                                .code(code)
                                .detailType(detailTypeEnum.getCode())
                                .sort(detailCommand.getSort())
                                .title(detailCommand.getTitle())
                                .content(detailCommand.getContent())
                                .detailStatus(TaskDatTaskDetailDetailStatusEnum.PENDING_PROCESSING.getCode())
                                .build()
                );
            }
            return;
        }
        Set<Long> existIds = new HashSet<>();
        List<TaskDatTaskDetailCommand> commandUpdateList = commandList.stream()
                .filter(one -> one.getId() != null).collect(Collectors.toList());
        for (TaskDatTaskDetailCommand detailCommand : commandUpdateList) {
            needUpdateList.add(
                    TaskDatTaskDetail.builder()
                            .id(detailCommand.getId())
                            .sort(detailCommand.getSort())
                            .title(detailCommand.getTitle())
                            .content(detailCommand.getContent())
                            .detailStatus(TaskDatTaskDetailDetailStatusEnum.PENDING_PROCESSING.getCode())
                            .build()
            );
            existIds.add(detailCommand.getId());
        }
        List<TaskDatTaskDetailCommand> commandInsertList = commandList.stream()
                .filter(one -> one.getId() == null).collect(Collectors.toList());
        for (TaskDatTaskDetailCommand detailCommand : commandInsertList) {
            needInsertList.add(
                    TaskDatTaskDetail.builder()
                            .code(code)
                            .detailType(detailTypeEnum.getCode())
                            .sort(detailCommand.getSort())
                            .title(detailCommand.getTitle())
                            .content(detailCommand.getContent())
                            .detailStatus(TaskDatTaskDetailDetailStatusEnum.PENDING_PROCESSING.getCode())
                            .build()
            );
        }
        for (TaskDatTaskDetailVO model : detailList) {
            if (!existIds.contains(model.getId())) {
                needDeleteList.add(model.getId());
            }
        }
    }

    /**
     * 构建任务操作记录
     *
     * @param code
     * @param operationTypeEnum
     * @return
     * @throws ServiceException
     */
    private TaskDatTaskOperate buildTaskOperate(String code, TaskDatTaskOperateOperationTypeEnum operationTypeEnum) throws ServiceException {
        return TaskDatTaskOperate.builder()
                .code(code)
                .detailType(null)
                .sort(null)
                .operationType(operationTypeEnum.getCode())
                .operationTime(new Date())
                .build();
    }

    /**
     * 构建任务操作明细记录
     *
     * @param code
     * @param detailType
     * @param sort
     * @param status
     * @return
     * @throws ServiceException
     */
    private TaskDatTaskOperate buildTaskOperateDetailByStatus(String code, int detailType, int sort, Integer status) throws ServiceException {
        Integer operationType;
        if (Objects.equals(status, TaskDatTaskDetailDetailStatusEnum.PENDING_PROCESSING.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.DETAIL_PENDING_PROCESSING.getCode();
        }
        else if (Objects.equals(status, TaskDatTaskDetailDetailStatusEnum.PROCESSING.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.DETAIL_PROCESSING.getCode();
        }
        else if (Objects.equals(status, TaskDatTaskDetailDetailStatusEnum.COMPLETED.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.DETAIL_COMPLETED.getCode();
        }
        else {
            throw new ServiceException("生成操作记录异常: 异常编码");
        }
        return TaskDatTaskOperate.builder()
                .code(code)
                .detailType(detailType)
                .sort(sort)
                .operationType(operationType)
                .operationTime(new Date())
                .build();
    }

    /**
     * 根据状态构建任务操作记录
     *
     * @param code
     * @param taskStatus
     * @return
     * @throws ServiceException
     */
    private TaskDatTaskOperate buildTaskOperateByStatus(String code, Integer taskStatus) throws ServiceException {
        Integer operationType;
        if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.TO_BE_DESIGNED.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.TO_BE_DESIGNED.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.DESIGN.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.DESIGN.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.TO_BE_DEVELOPED.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.TO_BE_DEVELOPED.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.DEVELOPING.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.DEVELOPING.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.JOINT_DEBUGGING_IN_PROGRESS.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.JOINT_DEBUGGING_IN_PROGRESS.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.TO_BE_TESTED.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.TO_BE_TESTED.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.DURING_TESTING.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.DURING_TESTING.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.TO_BE_RELEASED.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.TO_BE_RELEASED.getCode();
        }
        else if (Objects.equals(taskStatus, TaskDatTaskTabulationTaskStatusEnum.COMPLETED.getCode())) {
            operationType = TaskDatTaskOperateOperationTypeEnum.COMPLETED.getCode();
        }
        else {
            throw new ServiceException("生成操作记录异常: 异常编码");
        }
        return TaskDatTaskOperate.builder()
                .code(code)
                .detailType(null)
                .sort(null)
                .operationType(operationType)
                .operationTime(new Date())
                .build();
    }

}
